package com.xique.door.biz.service.impl;

import com.github.pagehelper.PageInfo;
import com.xique.common.core.utils.MathUtil;
import com.xique.common.core.utils.OrikaUtil;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.core.web.page.TableDataInfo;
import com.xique.door.bean.domain.*;
import com.xique.door.bean.dto.CardDeviceHouseCodeDTO;
import com.xique.door.bean.request.card.CardAddRequest;
import com.xique.door.bean.request.card.CardCommandSearchRequest;
import com.xique.door.bean.search.AreaBuildingHouseSearch;
import com.xique.door.bean.validation.CardValidation;
import com.xique.door.bean.vo.area.AreaBuildingHouseVo;
import com.xique.door.bean.vo.card.CardCommandVo;
import com.xique.door.bean.vo.card.CardUserVo;
import com.xique.door.biz.service.ICardBizService;
import com.xique.door.command.ICardCommandBizService;
import com.xique.door.device.freeview.constant.CommandStatus;
import com.xique.door.service.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: caogq @Date: 2022/2/25 16:35 @Description:
 */
@Service
public class CardBizServiceImpl implements ICardBizService {
    @Autowired
    private CardValidation cardValidation;

    @Autowired
    private IUserService userService;

    @Autowired
    private IDCardService dCardService;

    @Autowired
    private ICardCommandBizService cardCommandBizService;

    @Autowired
    private IDCardDeviceService cardDeviceService;

    @Autowired
    private IBuildHouseUserService houseUserService;

    @Autowired
    private IBuildHouseService buildHouseService;

    @Autowired
    private IAccessDeviceService accessDeviceService;

    @Autowired
    private IDCardHouseService cardHouseService;

    @Override
    public AjaxResult addCard(CardAddRequest request) {
        AjaxResult result = cardValidation.addCardValidation(request);
        if (AjaxResult.isError(result)) {
            return result;
        }
        DCard card = OrikaUtil.convert(request, DCard.class);

        card.setCreateUser(SecurityUtils.getUserId());
        card.setUpdateUser(SecurityUtils.getUserId());

        if (!CollectionUtils.isEmpty(request.getHouseIds())) {
            card.setHouseIds(StringUtils.join(request.getHouseIds(), ","));
        }

        DCard search = new DCard();
        search.setParkId(SecurityUtils.getParkId());
        search.setCardSn(card.getCardSn());
        List<DCard> dCards = dCardService.selectCardList(search);
        if (!dCards.isEmpty()) {
            //card =dCards.get(0);
            card.setId(dCards.get(0).getId());
            card.setStatus("1");
            dCardService.updateDCard(card);
            card = dCardService.selectDCardById(card.getId());
        } else {
            // 1、db：新增卡片
            card.setCustomId(System.currentTimeMillis() + MathUtil.getRandom(19));
            int count = dCardService.insertDCard(card);
            if (count < 0) {
                return AjaxResult.error("新增卡片失败");
            }
        }
        List<Long> houseIds = request.getHouseIds();
        if (CollectionUtils.isEmpty(houseIds)) {
            return AjaxResult.success();
        }

        // 3、db：中间表数据新增
        for (Long houseId : request.getHouseIds()) {
            // 新增房屋卡片表
            DCardHouse dCardHouse = new DCardHouse();
            dCardHouse.setHouseId(houseId);
            dCardHouse.setParkId(card.getParkId());
            dCardHouse.setCardId(card.getId());
            dCardHouse.setUserId(request.getUserId());
            cardHouseService.insertDCardHouse(dCardHouse);
        }
        List<CardDeviceHouseCodeDTO> dtos = houseUserService.selectHouseCodesByCard(card);
        if (dtos.isEmpty()) {
            return AjaxResult.success();
        }
        List<Long> deviceIds =
                dtos.stream()
                        .distinct()
                        .map(CardDeviceHouseCodeDTO::getDeviceId)
                        .collect(Collectors.toList());
        List<AccessDevice> accessDevices = accessDeviceService.selectAccessDeviceByIds(deviceIds);
        List<CardDevice> cardDevices = new ArrayList<>();
        for (AccessDevice accessDevice : accessDevices) {
            CardDevice cardDevice = new CardDevice();
            cardDevice.setDeviceId(accessDevice.getId());
            cardDevice.setParkId(request.getParkId());
            cardDevice.setCustomId(card.getCustomId());
            cardDevice.setCardSn(card.getCardSn());
            cardDevice.setModel(accessDevice.getModel());
            cardDevice.setStatus(CommandStatus.SEND);
            cardDevice.setDevSn(accessDevice.getDevSn());
            cardDevice.setCardId(card.getId());
            cardDevice.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
            cardDevice.setUpdateBy(cardDevice.getCreateBy());
            cardDeviceService.insertDCardDevice(cardDevice);
            cardDevices.add(cardDevice);
        }

        AjaxResult downResult = cardCommandBizService.downCard(card, cardDevices, dtos);
        return downResult;
    }

    @Override
    public AjaxResult deleteCard(Long cardId) {
        DCard card = dCardService.selectDCardById(cardId);
        CardDevice cardDevice = new CardDevice();
        cardDevice.setCardId(card.getId());
        List<CardDevice> cardDevices = cardDeviceService.selectDCardDeviceList(cardDevice);


        //解绑卡片与用户房屋的关系
        dCardService.updateUserHouse(cardId);
//    if (cardDevices.isEmpty()) {
//      // 卡片没有绑定房屋，直接删卡
//      int i = dCardService.deleteDCardById(cardId);
//      return i > 0 ? AjaxResult.success() : AjaxResult.error();
//    }
        AjaxResult result = cardCommandBizService.deleteCard(card, cardDevices);

        if (result.get("code").equals(200)) {
            for (CardDevice device : cardDevices) {
                /** 删除卡片与设备的中间表 */
                cardDeviceService.deleteDCardDeviceById(device.getId());
            }
            //删除卡与房屋的关系
            DCardHouse dCardHouse = new DCardHouse();
            dCardHouse.setCardId(cardId);
            List<DCardHouse> cardHouseList = cardHouseService.selectDCardHouseList(dCardHouse);
            for (DCardHouse cardHouse : cardHouseList) {
                cardHouseService.deleteDCardHouseById(cardHouse.getId());
            }
        }

        return result;
    }

    @Override
    public AjaxResult downCard(DCard card, List<CardDevice> cardDevices) {
        if (CollectionUtils.isEmpty(cardDevices)) {
            CardDevice search = new CardDevice();
            search.setCardId(card.getId());
            cardDevices = cardDeviceService.selectDCardDeviceList(search);
            if (cardDevices.isEmpty()) {
                return AjaxResult.success("");
            }
            for (CardDevice cardDevice : cardDevices) {
                cardDevice.setUpdateTime(new Date());
                cardDevice.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
                cardDevice.setStatus(CommandStatus.SEND);
            }
            cardDeviceService.batchUpdateCardDevice(cardDevices);
        }

        List<CardDeviceHouseCodeDTO> dtos = houseUserService.selectHouseCodesByCard(card);
        return cardCommandBizService.downCard(card, cardDevices, dtos);
    }

    @Override
    public AjaxResult downCards(Long deviceId) {
        return cardCommandBizService.downCards(deviceId);
    }

    @Override
    public TableDataInfo selectCardList(DCard dCard) {
        List<DCard> cards = dCardService.selectDCardList(dCard);
        List<CardUserVo> cardUserVos = OrikaUtil.converts(cards, CardUserVo.class);
        List<Long> cardIds = cards.stream().map(DCard::getId).collect(Collectors.toList());
        List<String> customIds = cards.stream().map(DCard::getCustomId).collect(Collectors.toList());
        List<CardDevice> cardDevices = new ArrayList<>();
        List<AreaBuildingHouseVo> areaInfos = new ArrayList<>();

        if (!cardIds.isEmpty()) {
            String houseIdStr = cards.stream().map(DCard::getHouseIds).collect(Collectors.joining(","));
            List<String> houseIds = Arrays.asList(houseIdStr.split(","));
            areaInfos =
                    buildHouseService.selecAreaBuildingHouseInfoByCondition(
                            new AreaBuildingHouseSearch(houseIds));
            cardDevices = cardDeviceService.selectDCardDeviceList(new CardDevice(cardIds));
        }

        for (CardUserVo cardUserVo : cardUserVos) {
            Long userId = cardUserVo.getUserId();
            User user = userService.selectUserById(userId);
            cardUserVo.setPhone(user.getPhone());
            cardUserVo.setUserName(user.getUserName());

            List<AreaBuildingHouseVo> cardAreaInfos = new ArrayList<>();
            // 根据卡片绑定的房屋id查询房屋信息
            if (StringUtils.isNotEmpty(cardUserVo.getHouseIds())) {
                List<String> cardHosueIds = Arrays.asList(StringUtils.split(cardUserVo.getHouseIds(), ","));
                for (String cardHosueId : cardHosueIds) {
                    AreaBuildingHouseVo cardAreaInfo =
                            areaInfos.stream()
                                    .filter(e -> cardHosueId.equals(e.getHouseId()))
                                    .findAny()
                                    .orElse(null);
                    cardAreaInfos.add(cardAreaInfo);
                }
            }

            cardUserVo.setAreaInfos(cardAreaInfos);
            List<CardDevice> cardDevice =
                    cardDevices.stream()
                            .filter(
                                    e ->
                                            e.getCardId().equals(cardUserVo.getId())
                                                    && !CommandStatus.SUCCESS.equals(e.getStatus()))
                            .collect(Collectors.toList());

            cardUserVo.setErrorStatus(cardDevice.isEmpty() ? "0" : "1");
        }
        TableDataInfo tableDataInfo =
                new TableDataInfo(cardUserVos, (int) new PageInfo(cards).getTotal());
        return tableDataInfo;
    }

    @Override
    public AjaxResult detail(String id) {
        DCard card = dCardService.selectDCardById(Long.valueOf(id));
        CardDevice cardDevice = new CardDevice();
        cardDevice.setCardId(Long.valueOf(id));
        List<CardDevice> cardDevices = cardDeviceService.selectDCardDeviceList(cardDevice);
        for (CardDevice device : cardDevices) {
            AccessDevice accessDevice = accessDeviceService.selectAccessDeviceById(device.getDeviceId());
            if (accessDevice != null) {
                device.setDeviceName(accessDevice.getName());
            }
        }
        card.setCardDevices(cardDevices);
        return AjaxResult.success(card);
    }

    @Override
    public AjaxResult loss(Long cardId) {
        int count = 0;
        DCard dCard = dCardService.selectDCardById(cardId);
        // 1、状态更新为禁用
        dCard.setStatus("0");
        count = dCardService.updateDCard(dCard);
        dCard.setIsLoss(true);
        // 2、下发至设备
        if (count > 0) {
            // 记录旧的卡号
            //            return cardCommandBizService.lossCard(dCard);
            //            User user = userService.selectUserById(dCard.getUserId());
            //            user.setCustomId(dCard.getCustomId());
            //            dCard.setOriginCardSn(dCard.getCardSn());
            //            CardDevice search = new CardDevice();
            //            search.setCardSn(dCard.getCardSn());
            //            List<CardDevice> cardDevices = cardDeviceService.selectDCardDeviceList(search);
            //            for (CardDevice cardDevice : cardDevices) {
            //                cardDevice.setStatus(CommandStatus.SEND);
            //                cardDevice.setUpdateTime(new Date());
            //                cardDevice.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
            //                cardDeviceService.updateDCardDevice(cardDevice);
            //            }
            //            dCard.setCardSn("0000000000");
            return this.downCard(dCard, null);
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult unLoss(Long cardId) {
        DCard dCard = dCardService.selectDCardById(cardId);

        // 1、状态更新为禁用
        dCard.setStatus("1");
        int count = dCardService.updateDCard(dCard);
        dCard.setIsLoss(false);
        // 2、下发至设备
        if (count > 0) {
            // 记录旧的卡号
            //            List<CardDeviceHouseCodeDTO> dtos =
            // houseUserService.selectHouseCodesByCard(dCard);

            this.downCard(dCard, null);
            //            User user = userService.selectUserById(dCard.getUserId());
            //            user.setCustomId(dCard.getCustomId());
            //            user.setCardSn(dCard.getCardSn());
            //            CardDevice cardDevice = new CardDevice();
            //            cardDevice.setCardSn(dCard.getCardSn());
            //            List<CardDevice> cardDevices =
            // cardDeviceService.selectDCardDeviceList(cardDevice);
            //            for (CardDevice device : cardDevices) {
            //                device.setStatus(CommandStatus.SEND);
            //                device.setUpdateTime(new Date());
            //                device.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
            //                cardDeviceService.updateDCardDevice(device);
            //            }
            //            this.downCard(dCard,cardDevices);
        }
        return AjaxResult.success();
    }

    /**
     * @param request
     * @description: 门卡同步记录查询
     * @author caogq
     * @date: 2022/3/5 10:46
     */
    @Override
    public TableDataInfo selectCardCommandList(CardCommandSearchRequest request) {
        List<CardCommandVo> cardCommandVos = cardDeviceService.selectCardCommandList(request);
        String houseIdStr =
                cardCommandVos.stream().map(CardCommandVo::getHouseIds).collect(Collectors.joining(","));
        List<String> houseIds = Arrays.asList(houseIdStr.split(","));
        List<AreaBuildingHouseVo> areaInfos =
                buildHouseService.selecAreaBuildingHouseInfoByCondition(
                        new AreaBuildingHouseSearch(houseIds));
        for (CardCommandVo cardCommandVo : cardCommandVos) {
            if (StringUtils.isNotEmpty(cardCommandVo.getHouseIds())) {
                List<String> cardHosueIds =
                        Arrays.asList(StringUtils.split(cardCommandVo.getHouseIds(), ","));
                // 根据卡片绑定的房屋id查询房屋信息
                List<AreaBuildingHouseVo> cardAreaInfos = new ArrayList<>();
                for (String cardHosueId : cardHosueIds) {
                    AreaBuildingHouseVo cardAreaInfo =
                            areaInfos.stream()
                                    .filter(e -> cardHosueId.equals(e.getHouseId()))
                                    .findAny()
                                    .orElse(null);
                    cardAreaInfos.add(cardAreaInfo);
                }
                cardCommandVo.setAreaInfos(cardAreaInfos);
            }
        }
        TableDataInfo tableDataInfo =
                new TableDataInfo(cardCommandVos, (int) new PageInfo(cardCommandVos).getTotal());
        return tableDataInfo;
    }
}
